import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { DiscordSnowflake } from "@sapphire/snowflake";
import { plainToInstance } from "class-transformer";
import { DataSource, In, Repository } from "typeorm";
import { ResultMsg } from "@/common/enum/result-msg.enum";
import Result from "@/common/utils/result.util";
import { SysDictItem } from "@/database/entity/SysDictItem";
import { SysDictType } from "@/database/entity/SysDictType";
import { CreateDictTypeDto } from "./dto/create-dict-type.dto";
import { PageDictTypeDto } from "./dto/page-dict-type.dto";
import { UpdateDictTypeDto } from "./dto/update-dict-type.dto";
import { DictTypeDetailVo } from "./vo/dict-type-detail.vo";
import { DictTypeListVo } from "./vo/dict-type-list.vo";

@Injectable()
export class DictTypeService {
    constructor(
        @InjectRepository(SysDictType) private readonly dictRepository: Repository<SysDictType>,
        @InjectRepository(SysDictItem) private readonly dictItemRepository: Repository<SysDictItem>,
        private dataSource: DataSource,
    ) {}

    /** 新增数据字典 */
    async create(data: CreateDictTypeDto) {
        const id = DiscordSnowflake.generate().toString();
        const newType = this.dictRepository.create({ ...data, id });
        await this.dictRepository.save(newType);
        return Result.success(id, ResultMsg.CREATE_SUCCESS);
    }

    /** 删除数据字典 */
    async remove(id: string) {
        const dictItems = await this.dictItemRepository.find({ where: { typeId: id } });
        await this.dataSource.transaction(async (manager) => {
            // 删除字典项
            if (dictItems.length > 0) {
                const dictItemIds = dictItems.map((item) => item.id);
                await manager.update(SysDictItem, { id: In(dictItemIds) }, { deletedAt: new Date() });
            }
            // 删除字典
            await manager.update(SysDictType, id, { deletedAt: new Date() });
        });
        return Result.success(null, ResultMsg.DELETE_SUCCESS);
    }

    /** 更新数据字典 */
    async update(data: UpdateDictTypeDto) {
        await this.dictRepository.update(data.id, { ...data });
        return Result.success(null, ResultMsg.UPDATE_SUCCESS);
    }

    /** 查询单个记录 */
    async findById(id: string): Promise<Result<DictTypeDetailVo>> {
        const record = await this.dictRepository.findOne({
            select: ["id", "name", "code", "remark"],
            where: { id },
        });
        const detailVo = plainToInstance(DictTypeDetailVo, record, { excludeExtraneousValues: true });
        return Result.success(detailVo);
    }

    /** 获取数据字典分页列表 */
    async page(data: PageDictTypeDto): Promise<Result<DictTypeListVo[]>> {
        const { name, code, pageNum, pageSize } = data;
        const queryBuilder = this.dictRepository.createQueryBuilder("type");

        if (name) {
            queryBuilder.andWhere("type.name LIKE :name", { name: `%${name}%` });
        }
        if (code) {
            queryBuilder.andWhere("type.code LIKE :code", { code: `%${code}%` });
        }

        queryBuilder
            .orderBy("type.createdAt", "DESC")
            .skip((pageNum - 1) * pageSize)
            .take(pageSize);

        const [list, total] = await queryBuilder.getManyAndCount();
        const voList = plainToInstance(DictTypeListVo, list, { excludeExtraneousValues: true });
        return Result.page(voList, { pageNum, pageSize, total });
    }
}
